﻿using System;
using System.Diagnostics.Contracts;

namespace O1.Data.Traversal.Expressions
{
    [ContractVerification(true)]
    internal class BinaryOrFilter : Filter
    {
        private readonly Filter left;

        private readonly Filter right;

        private readonly PropertyInterests propertyInterest;

        public BinaryOrFilter(Filter left, Filter right)
        {
            Contract.Requires<ArgumentNullException>(left != null);
            Contract.Requires<ArgumentNullException>(right != null);

            this.left = left;
            this.right = right;
            this.propertyInterest = left.PropertyInterest | right.PropertyInterest;
        }

        public override PropertyInterests PropertyInterest
        {
            get
            {
                return this.propertyInterest;
            }
        }

        public override ObservationInterests StartVertex(CellAddress vertex)
        {
            return this.left.StartVertex(vertex) | this.right.StartVertex(vertex);
        }

        public override ObservationInterests EndVertex(ObservationInterests vertexState)
        {
            return this.left.EndVertex(vertexState) | this.right.EndVertex(vertexState);
        }

        public override ObservationInterests StartEdge(Edge edge, EdgeDirections direction)
        {
            return this.left.StartEdge(edge, direction) | this.right.StartEdge(edge, direction);
        }

        public override ObservationInterests EndEdge(ObservationInterests edgeState)
        {
            return this.left.EndEdge(edgeState) | this.right.EndEdge(edgeState);
        }

        public override ObservationInterests Evaluate(DateProperty value)
        {
            return this.left.Evaluate(value) | this.right.Evaluate(value);
        }

        public override ObservationInterests Evaluate(DateTimeProperty value)
        {
            return this.left.Evaluate(value) | this.right.Evaluate(value);
        }

        public override ObservationInterests Evaluate(DecimalProperty value)
        {
            return this.left.Evaluate(value) | this.right.Evaluate(value);
        }

        public override ObservationInterests Evaluate(HashProperty value)
        {
            return this.left.Evaluate(value) | this.right.Evaluate(value);
        }

        public override ObservationInterests Evaluate(Int16Property value)
        {
            return this.left.Evaluate(value) | this.right.Evaluate(value);
        }

        public override ObservationInterests Evaluate(Int32Property value)
        {
            return this.left.Evaluate(value) | this.right.Evaluate(value);
        }

        public override ObservationInterests Evaluate(Int64Property value)
        {
            return this.left.Evaluate(value) | this.right.Evaluate(value);
        }

        public override ObservationInterests Evaluate(StringProperty value)
        {
            return this.left.Evaluate(value) | this.right.Evaluate(value);
        }

        [ContractInvariantMethod]
        private void ObjectInvariant()
        {
            Contract.Invariant(this.left != null);
            Contract.Invariant(this.right != null);
        }
    }
}
